home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
CW GUSI 1.6.4
/
src
/
GUSIMacFile.cp
< prev
next >
Wrap
Text File
|
1995-08-25
|
4KB
|
181 lines
/*********************************************************************
Project : GUSI - Grand Unified Socket Interface
File : GUSIMacFile.cp- Straight file sockets
Author : Matthias Neeracher <neeri@iis.ee.ethz.ch>
Language : MPW C++
$Log: GUSIFile.cp,v $
*********************************************************************/
#include "GUSIFile_P.h"
#include <IOCtl.h>
#pragma segment GUSI
/************************ AppleFileSocket members ************************/
MacFileSocket * MacFileSocket::open(const TFileSpec & spec, int flags)
{
char permission;
short fRef;
OSErr err;
MacFileSocket * sock;
switch (flags & 3) {
case O_RDONLY: permission = fsRdPerm; break;
case O_WRONLY: permission = fsWrPerm; break;
case O_RDWR: permission = fsRdWrPerm; break;
}
if (err = HOpenDF(spec.vRefNum, spec.parID, spec.name, permission, &fRef)) {
// File not found, but might be creatable
if (err == fnfErr && flags & O_CREAT) {
err = HCreate(spec.vRefNum, spec.parID, spec.name, 'MPS ', 'TEXT');
if (!err || err == dupFNErr)
err = HOpenDF(spec.vRefNum, spec.parID, spec.name, permission, &fRef);
}
switch (err) {
case noErr:
break;
case afpObjectTypeErr:
return (MacFileSocket *)GUSI_error_nil(EISDIR);
default:
if (File_error(err) == -1)
return (MacFileSocket *) nil;
}
} else if (flags & O_EXCL) {
FSClose(fRef);
return (MacFileSocket *)GUSI_error_nil(EEXIST);
}
if (flags & O_TRUNC)
SetEOF(fRef, 0);
sock = new MacFileSocket(fRef);
if (sock) {
sock->append = (flags & O_APPEND) != 0;
return sock;
} else {
FSClose(fRef);
return (MacFileSocket *)GUSI_error_nil(ENOMEM);
}
}
int MacFileSocket::read(void * buffer, int buflen)
{
OSErr err;
long length = buflen;
switch (err = FSRead(fRefNum, &length, buffer)) {
case eofErr:
case noErr:
return int(length);
default:
return File_error(err);
}
}
int MacFileSocket::write(void * buffer, int buflen)
{
long length = buflen;
PrepareWrite();
if (File_error(FSWrite(fRefNum, &length, buffer)))
return -1;
else
return int(length);
}
int MacFileSocket::ioctl(unsigned int request, void *argp)
{
switch (request) {
case FIONREAD:
long eof;
long pos;
if (File_error(GetEOF(fRefNum, &eof)))
return -1;
if (File_error(GetFPos(fRefNum, &pos)))
return -1;
*(long *) argp = eof - pos;
return 0;
default :
return FileSocket::ioctl(request, argp);
}
}
long MacFileSocket::lseek(long offset, int whence)
{
long eof;
long pos;
if (File_error(GetEOF(fRefNum, &eof)))
return -1;
switch (whence) {
case SEEK_CUR:
if (File_error(GetFPos(fRefNum, &pos)))
return -1;
break;
case SEEK_END:
pos = eof;
break;
case SEEK_SET:
pos = 0;
break;
default:
return GUSI_error(EINVAL);
}
pos += offset;
if (pos > eof) {
if (File_error(SetFPos(fRefNum, fsFromStart, eof)))
return -1;
char * buf = NewPtrClear(1024);
long portion = 1;
long rest;
for (rest = pos - eof; rest && portion; rest -= portion) {
portion = rest > 1024 ? 1024 : rest;
if (File_error(FSWrite(fRefNum, &portion, buf))) {
DisposPtr(buf);
return -1;
}
}
DisposPtr(buf);
if (rest)
return GUSI_error(ENOSPC);
} else if (pos < 0)
return GUSI_error(EINVAL);
return File_error(SetFPos(fRefNum, fsFromStart, pos)) ? -1 : pos;
}
int MacFileSocket::ftruncate(long offset)
{
long pos;
if (lseek(offset, SEEK_SET) == -1)
return -1;
if (File_error(GetFPos(fRefNum, &pos)))
return -1;
return File_error(SetEOF(fRefNum, pos));
}
MacFileSocket::~MacFileSocket()
{
FSClose(fRefNum);
}